home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 26 / AACD 26.iso / AACD / Programming / ace_gpl_release / src / lib / c / iff.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-10-04  |  7.7 KB  |  362 lines

  1. /*
  2. ** IFF code for ACE **
  3. ** Copyright (C) 1998 David Benn
  4. ** 
  5. ** This program is free software; you can redistribute it and/or
  6. ** modify it under the terms of the GNU General Public License
  7. ** as published by the Free Software Foundation; either version 2
  8. ** of the License, or (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program; if not, write to the Free Software
  17. ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  18. **
  19. **      Author: David J Benn, with thanks to Jeff Glatt for his
  20. **        excellent ILBM.library (the one that CBM should
  21. **        have adopted as a standard shared library).
  22. **
  23. **        Date: 27th February 1994,
  24. **        4th April 1994,
  25. **        3rd,5th,7th,10th,11th,19th,21st,28th August 1994,
  26. **        10th,11th September 1994
  27. */
  28.  
  29. #include  <exec/types.h>
  30. #include  <libraries/dos.h>
  31. #include  <intuition/intuition.h>
  32. #include  "ilbm_lib.h"
  33.  
  34. /* errors */
  35. #define OPEN_ERR    500
  36. #define CLOSE_ERR    501
  37. #define READ_ERR    502
  38. #define BAD_CHAN    503
  39.  
  40. #define MINCHANNEL    1
  41. #define MAXCHANNEL    255
  42.  
  43. #define CLEARED_ANY_MEM 7L
  44.  
  45. /* globals */
  46. char *ilbm = "ILBM";              /* chunk identifiers */
  47. char *acbm = "ACBM";
  48.  
  49. long     rLen;                   /* bytes read from disc */
  50. long     icLen;                  /* chunk length */
  51. UBYTE     mybuf[300];           /* buffer for headers and short chunks */
  52.  
  53. BOOL    first=TRUE;
  54.  
  55. struct    Library    *ILBMBase = NULL;
  56.  
  57. typedef    struct IFFpic{
  58.     char     *name;
  59.     char    pictype[5];
  60.     LONG    width;
  61.     LONG    height;
  62.     LONG    depth;
  63.     struct    Window    *window;
  64.     struct    Screen    *screen;
  65. } IFFPIC;
  66.  
  67. IFFPIC    iffpic[MAXCHANNEL+1];        /* Need: 1..255 */
  68.  
  69. /* externals */
  70. extern struct Screen *Screen_list[10];
  71. extern LONG error_code;
  72.  
  73. /* function protos */
  74. BOOL    bad_channel();
  75. void    IFFPicOpen();
  76. void    IFFPicRead();
  77. void    IFFPicClose();
  78. LONG    iff_func();
  79. void    readiff();
  80.  
  81. /* external functions */
  82. extern    void     *alloc();
  83. extern    void    stringcopy();
  84. extern    LONG    stringcompare();
  85. extern    ULONG    stringlength();
  86. extern    LONG    LoadIFFToWindow();
  87.  
  88. /*--------Interface functions-------*/
  89.  
  90. BOOL bad(channel)
  91. LONG channel;
  92. {
  93. /* Do we have a "bad" channel? */
  94.  
  95.     if (channel < MINCHANNEL  || channel > MAXCHANNEL) 
  96.         return(TRUE);
  97.     else
  98.         return(FALSE);        
  99. }
  100.  
  101. void IFFPicOpen(name,channel)
  102. char *name;
  103. LONG channel;
  104. {
  105. struct FileHandle *fHandle;
  106. /* 
  107. ** Retrieve and store info' about an IFF picture file. 
  108. */
  109. LONG i;
  110.     if (first)
  111.     {
  112.         first = FALSE;
  113.  
  114.         for (i=1;i<MAXCHANNEL;i++)
  115.         {    
  116.             iffpic[i].name          = NULL;
  117.             iffpic[i].pictype[0]     = '\0';
  118.             iffpic[i].width        = 0;
  119.             iffpic[i].height    = 0;
  120.             iffpic[i].depth     = 0;
  121.             iffpic[i].screen     = NULL;
  122.             iffpic[i].window     = NULL;
  123.         }
  124.     }
  125.  
  126.       if (bad(channel))
  127.         { error_code = BAD_CHAN; return; }
  128.       else
  129.       {
  130.         if (iffpic[channel].name != NULL)
  131.             { error_code = OPEN_ERR; return; }
  132.     
  133.         /* 
  134.         ** Read IFF header info' and store 
  135.         ** width, height and depth. 
  136.         */
  137.         fHandle = (struct FileHandle *)Open(name,MODE_OLDFILE);
  138.           if (fHandle == NULL) 
  139.            { error_code = OPEN_ERR; return; }
  140.  
  141.           rLen = Read(fHandle,&mybuf[0],12);
  142.  
  143.         /* ACBM or ILBM picture file? */
  144.           if (stringcompare(ilbm,&mybuf[0]+8) != 0 &&
  145.               stringcompare(acbm,&mybuf[0]+8) != 0)
  146.         {
  147.             error_code = READ_ERR;
  148.             return;        
  149.         }
  150.         
  151.         iffpic[channel].pictype[0] = mybuf[8];
  152.         iffpic[channel].pictype[1] = mybuf[9];
  153.         iffpic[channel].pictype[2] = mybuf[10];
  154.         iffpic[channel].pictype[3] = mybuf[11];
  155.         iffpic[channel].pictype[4] = '\0';
  156.  
  157.           rLen = Read(fHandle,&mybuf[0],8);
  158.  
  159.           icLen=mybuf[7]+256*mybuf[6];
  160.  
  161.           rLen = Read(fHandle,&mybuf[0],icLen);
  162.  
  163.         if (fHandle) Close(fHandle);
  164.  
  165.         iffpic[channel].width     = mybuf[17] + 256*mybuf[16];
  166.         iffpic[channel].height     = mybuf[19] + 256*mybuf[18];
  167.         iffpic[channel].depth     = mybuf[8];   /* # of bitplanes */
  168.  
  169.         /* Store name */
  170.         iffpic[channel].name = (char *)alloc(CLEARED_ANY_MEM,
  171.                              stringlength(name)+1);
  172.  
  173.         if (iffpic[channel].name == NULL)
  174.             { error_code = OPEN_ERR; return; }
  175.  
  176.         stringcopy(iffpic[channel].name,name);
  177.     }
  178. }
  179.  
  180. void IFFPicRead(screen_id,channel)
  181. LONG screen_id,channel;
  182. {
  183. /*
  184. ** Read IFF picture onto specified screen.
  185. */
  186.       if (bad(channel))
  187.         { error_code = BAD_CHAN; return; }
  188.       else
  189.       {
  190.         if (iffpic[channel].name == NULL)
  191.             { error_code = BAD_CHAN; return; }    
  192.  
  193.          readiff(screen_id,channel);
  194.     }
  195. }
  196.  
  197. void IFFPicClose(channel)
  198. LONG channel;
  199. {
  200. /* 
  201. ** Clean up IFF channel.
  202. */
  203.  
  204.       if (bad(channel))
  205.         { error_code = BAD_CHAN; return; }
  206.       else
  207.       {
  208.         if (iffpic[channel].name == NULL)
  209.             { error_code = CLOSE_ERR; return; }
  210.  
  211.         /*
  212.         ** Close screen and window opened by
  213.         ** ILBM.library?
  214.         */
  215.         if (iffpic[channel].window)
  216.         {
  217.             CloseWindow(iffpic[channel].window);
  218.         }
  219.  
  220.         if (iffpic[channel].screen)
  221.         {
  222.             CloseScreen(iffpic[channel].screen);
  223.         }
  224.     
  225.         /*
  226.         ** Clear all fields of IFFPic structure.
  227.         */
  228.         iffpic[channel].name     = NULL;
  229.         iffpic[channel].pictype[0] = '\0';
  230.         iffpic[channel].width     = 0;
  231.         iffpic[channel].height     = 0;
  232.         iffpic[channel].depth     = 0;
  233.         iffpic[channel].screen     = NULL;
  234.         iffpic[channel].window     = NULL;
  235.     }
  236. }
  237.  
  238. LONG iff_func(n,channel)
  239. LONG n,channel;
  240. {
  241. /*
  242. ** Return info' about IFF picture on channel N.
  243. */
  244.  
  245.       if (bad(channel))
  246.         { error_code = BAD_CHAN; return; }
  247.  
  248.     if (iffpic[channel].name == NULL)
  249.         { error_code = READ_ERR; return; }
  250.     
  251.     switch(n)
  252.     {
  253.         case 0    :    return((LONG)&iffpic[channel].pictype[0]);  
  254.                 break;
  255.  
  256.         case 1    :    return(iffpic[channel].width);    break;
  257.  
  258.         case 2    :    return(iffpic[channel].height);    break;
  259.  
  260.         case 3    :    return(iffpic[channel].depth);    break;
  261.  
  262.         case 4    :    /* hold-and-modify (HAM) */
  263.                 if (iffpic[channel].depth == 6) return(5L);
  264.                 else
  265.                 /* hi-res interlaced */
  266.                 if (iffpic[channel].width > 320 &&
  267.                     iffpic[channel].height > 200) return(4L);
  268.                 else
  269.                 /* lo-res interlaced */
  270.                 if (iffpic[channel].width <= 320 &&
  271.                     iffpic[channel].height > 200) return(3L);
  272.                 else
  273.                 /* hi-res */
  274.                 if (iffpic[channel].width > 320 &&
  275.                     iffpic[channel].height <= 200) return(2L);
  276.                 else
  277.                 /* lo-res */
  278.                     return(1L);
  279.                 break;
  280.                     
  281.         default    :    return(0L);
  282.                 break;
  283.     }
  284. }
  285.  
  286. void    readiff(screen_id,channel)
  287. LONG    screen_id,channel;
  288. {
  289. /*
  290. ** Read and display an IFF image.
  291. */
  292. ILBMFrame *picframe;
  293. struct Screen *screen;
  294.  
  295.     /* 
  296.     ** Open ILBM library. Look in LIBS: then in RAM:ILBMtmp.
  297.     */
  298.     ILBMBase = (struct Library *)OpenLibrary("ilbm.library",0L);
  299.  
  300.     if (ILBMBase == NULL) ILBMBase = (struct Library *)
  301.                      OpenLibrary("ram:ILBMtmp/ilbm.library",0L);
  302.  
  303.     if (ILBMBase == NULL) { error_code = READ_ERR; return; }
  304.  
  305.     /* 
  306.     ** Setup ILBMFrame structure. 
  307.     */
  308.     if (screen_id == -1L || (screen_id >= 1 && screen_id <= 9))
  309.     {
  310.         picframe = (ILBMFrame *)alloc(CLEARED_ANY_MEM,sizeof(ILBMFrame));
  311.         if (picframe == NULL) 
  312.         { 
  313.         error_code = READ_ERR;
  314.         if (ILBMBase) CloseLibrary(ILBMBase);
  315.         return;
  316.     }
  317.     
  318.     if (screen_id != -1L)
  319.     {
  320.         /* 
  321.         ** Use supplied screen and its default window
  322.         ** otherwise let ILBM.library define its own.
  323.         */
  324.         screen = Screen_list[screen_id];
  325.             picframe->iScreen = screen;
  326.              picframe->iWindow = screen->FirstWindow;
  327.     }
  328.  
  329.         /*
  330.     ** Read and display picture! 
  331.     */
  332.         if (LoadIFFToWindow(iffpic[channel].name,picframe) != 0)
  333.                error_code=READ_ERR;
  334.  
  335.     /*
  336.     ** Store address of window and screen opened by ILBM.library? 
  337.     ** [see also IFFPicClose()].
  338.     */
  339.     if (screen_id == -1L)
  340.     {
  341.         /*
  342.         ** Yes.
  343.         */
  344.         iffpic[channel].screen = picframe->iScreen;
  345.         iffpic[channel].window = picframe->iWindow;
  346.     }
  347.     else
  348.     {
  349.         /* 
  350.         ** No! User is responsible for cleaning up
  351.         ** open screen and window.
  352.         */
  353.         iffpic[channel].screen = NULL;
  354.         iffpic[channel].window = NULL;
  355.     }
  356.     }
  357.     else
  358.     error_code = READ_ERR;
  359.  
  360.     if (ILBMBase) CloseLibrary(ILBMBase);
  361. }
  362.